package com.ruoyi.access.util;

import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import java.io.*;
import java.nio.charset.StandardCharsets;
import java.util.Base64;

/**
 * 对称加密工具类（基于 AES）
 * 支持：密钥生成、加密、解密、文件保存与读取
 */
public class SymmetricCryptoUtil {

    private static final String ALGORITHM = "AES";

    /**
     * 生成对称密钥（AES 256位）
     */
    public static String generateAESKey() throws Exception {
        KeyGenerator keyGen = KeyGenerator.getInstance(ALGORITHM);
        keyGen.init(256);
        SecretKey secretKey = keyGen.generateKey();
        return Base64.getEncoder().encodeToString(secretKey.getEncoded());
    }

    /**
     * 使用对称密钥加密数据
     */
    public static String encrypt(String plainText, String base64Key) throws Exception {
        byte[] decodedKey = Base64.getDecoder().decode(base64Key);
        SecretKeySpec secretKey = new SecretKeySpec(decodedKey, ALGORITHM);

        Cipher cipher = Cipher.getInstance(ALGORITHM);
        cipher.init(Cipher.ENCRYPT_MODE, secretKey);
        byte[] encrypted = cipher.doFinal(plainText.getBytes(StandardCharsets.UTF_8));

        return Base64.getEncoder().encodeToString(encrypted);
    }

    /**
     * 使用对称密钥解密数据
     */
    public static String decrypt(String cipherText, String base64Key) throws Exception {
        byte[] decodedKey = Base64.getDecoder().decode(base64Key);
        SecretKeySpec secretKey = new SecretKeySpec(decodedKey, ALGORITHM);

        Cipher cipher = Cipher.getInstance(ALGORITHM);
        cipher.init(Cipher.DECRYPT_MODE, secretKey);
        byte[] decrypted = cipher.doFinal(Base64.getDecoder().decode(cipherText));

        return new String(decrypted, StandardCharsets.UTF_8);
    }

    /**
     * 将 Base64 编码的密钥保存到文件
     * @param base64Key 密钥字符串
     * @param filePath  文件路径，例如 "D:/keys/aes.key"
     */
    public static void saveKeyToFile(String base64Key, String filePath) throws IOException {
        File file = new File(filePath);
        // 创建父目录（如果不存在）
        file.getParentFile().mkdirs();
        try (BufferedWriter writer = new BufferedWriter(new FileWriter(file))) {
            writer.write(base64Key);
        }
    }

    /**
     * 从文件中读取 Base64 编码的密钥
     * @param filePath 文件路径
     * @return Base64 编码的密钥字符串
     */
    public static String loadKeyFromFile(String filePath) throws IOException {
        StringBuilder sb = new StringBuilder();
        try (BufferedReader reader = new BufferedReader(new FileReader(filePath))) {
            String line;
            while ((line = reader.readLine()) != null) {
                sb.append(line);
            }
        }
        return sb.toString();
    }

    /**
     * 简单测试
     */
    public static void main(String[] args) throws Exception {
        // 1️⃣ 生成密钥
        String key = generateAESKey();
        System.out.println("生成的AES密钥(Base64): " + key);

        // 2️⃣ 保存密钥
        String keyFilePath = "D:/Workspace/Master_work/code/Did_accessControl/aes.key";
        saveKeyToFile(key, keyFilePath);
        System.out.println("密钥已保存至: " + keyFilePath);

        // 3️⃣ 从文件加载密钥
        String loadedKey = loadKeyFromFile(keyFilePath);
        System.out.println("读取密钥: " + loadedKey);

        // 4️⃣ 加密/解密测试
        String data = "Access Control Test";
        String encrypted = encrypt(data, loadedKey);
        String decrypted = decrypt(encrypted, loadedKey);

        System.out.println("加密后: " + encrypted);
        System.out.println("解密后: " + decrypted);
    }
}
